// function Person(name) {
//   this.name = name
// }
// Person.prototype.say = function () {
//   console.log(`My name is ${this.name}`)
// }

// const person = new Person('tom')
// person.say()

// class
// 普通的实例属性/方法，通过new实例后，可访问
// static 静态属性/方法，直接通过构造函数访问
// #私有属性/方法，只能在内部调用
class Person {
  constructor(name) {
    this.name = name
  }
  say() {
    // this.#update()
    console.log(`My name is ${this.name}`)
  }
  // static create() {
  //   console.log('static')
  // }
  // #update() {
  //   console.log('update')
  // }
}

// const person = new Person('tom')
// person.say()
// Person.create()

// person.update()

// extends
class Student extends Person {
  constructor({ name, age }) {
    super(name)
    this.age = age
  }
  say() {
    console.log('子类say')
  }
  info() {
    this.say()
    super.say()
    // console.log(this.name, this.age, this.say)
  }
}

// const student = new Student({ name: 'lisi', age: 18 })
// console.log(student, 'student')
// student.info()
// console.log(student.constructor === Student)
// console.log(student.__proto__ === Student.prototype)
// console.log(Student.prototype.constructor === Student)

// console.log(new Array())

// console.log(Object.prototype.__proto__)
// 异步 promise
// wx.request({
//   success: () => {
//     wx.request({
//       success: () => {
//         wx.request({
//           success: () => {

//           }
//         })
//       }
//     })
//   }
// })

// 1.接收执行器，执行器里面接受两个参数，参数分别是成功回调，失败回调
// 2.promise本身有三种状态 pending（等待）、fulfilled(成功)、rejected(失败)，状态一旦从pending更改后，就不再发生变化
// 3. 调用resolve,会将promise的状态改为成功，然后执行then中的成功回调；调用reject，会将promise的状态改为失败，执行then中的失败回调
// 4. promise的then方法可以多次调用，但并不改变promise的状态
// 5. promise的then支持链式调用，如果前一个then返回不是promise，将返回的值直接传给后续的then方法中的参数；如果为promise，将返回promise的作为后续then方法对应的实例promise对象


// Promise.all接受一个数组，数组里面每一项都为promise，当所有promise的状态都为成功时，才会执行对应的then方法中的成功回调，否则，有一个失败，则为失败
// Promise.race接受一个数组，数组里面每一项都为promise,有一个成功，就会成功

// const promise = new Promise((resolve, reject) => {
//   resolve('success')
// })


// const promise1 = new Promise((resolve, reject) => {
//   // resolve('promise1 success')
//   reject('error promise1')
// })

// promise.then(res => {
//   console.log(res, 'res')
//   return promise1
// }).then(res => {
//   console.log(res, 'second')
// }, err => {
//   console.log(err, 'second err')
// }).then(res => {

// })

// const ajax = (url) => {
//   return fetch(' http://localhost:3000' + url).then(res => {
//     // console.log(res)
//     if (res.status === 200) {
//       return res.json()
//     } else {
//       return Promise.reject(new Error('请求失败'))
//     }
//   })
// }
// ajax('/lists').then(res => {
//   console.log(res, 'value')
// }, err => {
//   console.log('err', err)
// })

// const urls = ['/list', '/user', '/lists']

// const itemPromise = (url) => {
//   return new Promise((resolve, reject) => {
//     ajax(url).then(res => {
//       resolve({
//         success: true,
//         data: res
//       })
//     }, err => {
//       resolve({
//         success: false,
//         err: err
//       })
//     })
//   })
// }

// Promise.all(urls.map(item => itemPromise(item))).then(res => {
//   console.log(res, 'res')
// }).catch(err => {
//   console.log(err, 'err')
// })


// 1.接收执行器，执行器里面接受两个参数，参数分别是成功回调，失败回调
// 2.promise本身有三种状态 pending（等待）、fulfilled(成功)、rejected(失败)，状态一旦从pending更改后，就不再发生变化
// 3. 调用resolve,会将promise的状态改为成功，然后执行then中的成功回调；调用reject，会将promise的状态改为失败，执行then中的失败回调
// 4. promise的then方法可以多次调用，但并不改变promise的状态
// 5. promise的then支持链式调用，如果前一个then返回不是promise，将返回的值直接传给后续的then方法中的参数；如果为promise，将返回promise的作为后续then方法对应的实例promise对象

class MyPromise {
  constructor(fn) {
    fn(this.resolve, this.reject)
  }
  status = 'pending'
  successCallback = []
  failCallback = []
  value = undefined
  reason = undefined
  resolve = (value) => {
    if (this.status !== 'pending') return
    this.status = 'fulfilled'
    this.value = value
    // console.log(this.successCallback)
    // this.successCallback && this.successCallback(value)
    while (this.successCallback.length) {
      this.successCallback.shift()(value)
    }
  }
  reject = (reason) => {
    if (this.status !== 'pending') return
    this.status = 'rejected'
    this.reason = reason
    // this.failCallback && this.failCallback(reason)
    while (this.failCallback.length) {
      this.failCallback.shift()(reason)
    }
  }
  then(successCallback, failCallback) {
    const promise2 = new MyPromise((resolve, reject) => {
      if (this.status === 'fulfilled') {
        let result = successCallback(this.value)
        handleResolve(result, resolve, reject)
        // resolve(result)
      } else if (this.status === 'rejected') {
        failCallback(this.reason)
      } else {
        this.successCallback.push(successCallback)
        this.failCallback.push(failCallback)
      }
    })
    return promise2

  }
}


const handleResolve = (result, resolve, reject) => {
  if (result?.constructor === MyPromise) {
    result.then(resolve, reject)
  } else {
    resolve(result)
  }
}

// const promise = new MyPromise((resolve, reject) => {
//   // reject('失败')
//   // resolve('成功')
//   resolve('成功')

// })

// const p2 = new MyPromise((resolve, reject) => {
//   reject('p2 fail')

// })
// // console.log(promise, 'promise')
// promise.then(res => {
//   console.log(res, 'success1')
//   // return p2
//   // return 
// }, err => {
//   console.log(err, 'err')
// }).then(res => {
//   console.log(res, 'res')
// }, err => {
//   console.log(err, 'err p2')
// })

// const loadImg = (callback) => {
//   const url = 'https://img0.baidu.com/it/u=925843206,3288141497&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=769';
//   const image = new Image()
//   image.onload = () => {
//     callback()
//   }
//   image.onerror = () => {

//   }
//   image.src = url
// }

// const loadImg = (index) => {
//   return new Promise((resolve, reject) => {
//     const url = 'https://img0.baidu.com/it/u=925843206,3288141497&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=769';
//     const image = new Image()
//     image.onload = (res) => {
//       setTimeout(() => {
//         resolve(index)
//       }, 500)

//     }
//     image.onerror = (err) => {
//       reject(err)
//     }
//     image.src = url
//   })
// }


// new Array(10).fill(loadImg).reduce((prev, next, index) => {
//   return prev.then(res => {
//     console.log(res)
//     return next(index)
//   })
// }, Promise.resolve())

const p1 = new Promise((resolve, reject) => {
  resolve('p1 success')
})

const p2 = new Promise((resolve, reject) => {
  resolve('p2 success')
})

// generator
function* main() {

  const result = yield p1
  console.log(result)
  yield p2
}
const generator = main();
generator.next().value.then(res => {
  generator.next(res).value.then(res => {
    // console.log('second', res)
  })
})
// console.log(generator.next())
// async await是generator的语法糖

// const load = async () => {
//   try {
//     const result = await ajax()
//   } catch (err) {
//     console.log(err)
//   }

// }

async function async1() {
  console.log('async1 start');
  await async2();
  console.log('asnyc1 end');
}

async function async2() {
  console.log('async2');
}

console.log('script start');

setTimeout(() => {
  console.log('setTimeOut');
}, 0);

async1();
new Promise(function (reslove) {
  console.log('promise1');
  reslove();
}).then(function () {
  console.log('promise2');
})
console.log('script end');

// script start
// async1 start
// async2
// promise1
// script end
// asnyc1 end
// promise2
// setTimeOut











